/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 

/*Why me?
This file exists to provide a object related view of data in a flat file.
It does this similarly, but far more simply, to xml.  It also bares mark resemblence
to xml, html, sgml, etc.  However, it bares no real technical resemblence:
IT IS SIMPlE AND WILL REMAIN SIMPLE.

xml_open is only for diary files.

xml_scanf is a great function to use for your own generic purposes.
It's not necessarily as fast as calling xml_getTag yourself, but it's 
like working with scanf and is very helpful and PLENTY FAST.

xml_printf doesn't work yet.  Save yourself time, don't use it
until I figure out how it makes sense to have it work!

*/

 
#ifndef ELOG_XML_CC
#define ELOG_XML_CC

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "io.h"
#include "dict.h"





//char *elog_xml_getTag(char *doc, char *tagName, char* attributes);
char *elog_xml_getTag(char *doc, char *tagName[]);
//Pre:tagName is a valid c string, it is formatted as such:
//parent->child->child->child  these all being nested tags
//Post: returns the contents of that tag, or NULL if it does not exist
//or if it does not contain data it returns a string containing a list of children
//for that tag.





char *elog_xml_tagCapture(const char *doc, char *tag);
//Pre: doc & tag are valid c strings
//Post:  returns <tag> to </tag> inside doc, or null is tag is not found

char *elog_xml_stripWhiteSpace(const char *doc);
//For removing the excess surrounding whitespace that will be added by write formats
//Pre:  the text of a tag, preferably a leaf tag (meaning it has no child tags)
//Post:  returns a new c string without the leading and ending whitespace





//These are great small helper functions:
unsigned int elog_xml_getShort(char *tag, char *doc);
//Pre:  doc contains the text with only one occurance of tag in it, tag is a tag in form <stuff>
//Post:  returns the number contained in the tag inside doc, if there's an error you won't know;
//so don't send this function things that aren't numbers

char *elog_xml_getChar(char *tag, char *doc);
//Pre:doc contains the text with only one occurance of tag in it, tag is a tag in form <stuff>
//Post:  returns the text inside tag, minus surrounding whitespace.


int elog_xml_unreadify(char *xml);
//Pre:  xml is a valid document
//Post:  removes unecessary whitespace, does not reallocate your array either!
//Returns:  the length of the modified document (this is for internal optimizations)


char *elog_xml_readify(const char *xml, int length);
//Pre: xml is a valid xml file.  length may be -1 if you don't know.
//Post:  Returns a copy of it, but indented for readability
//You aren't safe using this on any data so
//A common usage may look like:
//char *pretty = elog_xml_readify(xml, elog_xml_unreadify(xml));
//This will fix it, regardless, to the shorter way.  but xml will be altered.
//Then the length value from the unreadify is passed in and used.
//This avoids an strlen call.


int elog_xml_printf(char *xml, char *template, const char *tag,
					const char *data);
//Pre:  tag is a tag and data is its data.  Templace takes the same form as scanf
//Post:  tag and data is inserted into xml in the spot dictated by template
//Template format:  "meta.object.child1%s"
//You must use %x for xml data otherwise you'll mess it up badly.

char *elog_xml_start(const char *tag, unsigned int size); 
//Pre:  size is the size that will be allowed.
//Post:  Starts an xml file:  tag="<tag>" 
//return="<tag>
//</tag>"


void elog_xml_scanf(const char *meta, char *template, void *res);
//Pre:  meta must be valid xml data
//Post:  template is evaluated this way object-object-%datatype, so an example:
/*
 * "<meta>.<timestamps>.<last_edit>.%s"
 * This would open meta, then open timestamps in it, then open last_edit in it.
 * It would then evaluate what it has as a string.

 * %   s    String
 * %   i    integer


*/

void **elog_xml_scanl(const char *meta, const char *template, const char *tag, void* (*callback)(char *));
//Pre:  meta is an xml doc, template is of given form, and callback is a function taking one argument, returning one.
//Post:  Calls callback for every occurance of given path in template.
//template:  "<meta>.<attachments>", "<attchmnt>"
/*
	void *call(char *xml)
	{
		struct elog_xml_attchmnt *ret = malloc(sizeof *ret);
		elog_xml_scanf(xml, "<attchmnt>.<name>.%s", &(ret->name));
		elog_xml_scanf(xml, "<attchmnt>.<location>.%s", &(ret->loc));
		return ret;
	}

*/

void elog_xml_printl(char *meta, const char *template, const char *tag, const char *subTag, int (*callback)(void *, char *, const char *), void **data, int estDatSize);
//Pre:  meta is an xml doc.  template is of the given form, and callback is a function taking a data-type (probably struct of some form).  And callback returns a valid xml doc.
//tag is the root tag for the list
//subtag is the tag surrounding each item.
//estDatSize is the estimated space for your data with strings.
//Going big is better than small.
//data is the data to be put in, MUST be null terminated.

//Post:  A list of tags is placed into the final tag on template (this tag is created), each of the list is inside tag named "tag", and callback is used to generate each tree.
//Example:
/*
	int call(void *dat, char *xml, const char *tag)
	{
		struct elog_xml_attchmnt *data = dat;
		//we know xml is a valid, existing xml document space.
		//we know that tag is the root tag for it.
		char *temp;
		elog_sp_cat(&temp, tag, ".%s", NULL);
		if (elog_xml_printf(xml, temp, "<name>", data->name))
		{
			free(temp);
			return 1; //error!
		}
		if (elog_xml_printf(xml, temp, "<loc>", data->loc))
		{
			free(temp);
			return 1; //error!
		}
		free(temp);
		return 0; //success!
	}
*/





#endif
